package com.gitlab.lucky.auto.tld;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.gitlab.lucky.auto.tld.phone.Phone;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileWriter;
import java.util.Base64;

public class Tld {
	private static final Logger logger = LoggerFactory.getLogger(Tld.class);
	/**
	 * 注册数量
	 */
	private static final int REGISTER_COUNT = 20;
	public static void main(String[] args) throws Exception {
		System.setProperty("webdriver.gecko.driver","geckodriver");
		java.io.FileWriter fileWriter = new java.io.FileWriter("phone.txt",true);
		String token = Phone.getToken();
		FirefoxDriver chromeDriver = new FirefoxDriver();
		for (int i = 0; i < REGISTER_COUNT; i++) {
			String phoneNum = Phone.getPhoneNum(token);
			chromeDriver.get("https://user.teld.cn/newsignin?phonenum=%2086&mobile="+phoneNum+"&redirect_uThhttps%3A%2F%2Fwww.teld.cn%2F&source=2");
			Thread.sleep(5000L);
			WebElement slider = chromeDriver.findElementByClassName("sliderBG");
			String style = slider.getAttribute("style");
			Assert.isTrue(StrUtil.isNotBlank(style));
			String base64 = style.split("base64,")[1].split("\"")[0];
			String s = updateWidth(base64);
			Integer x = getX(s);
			move(chromeDriver,x);
			WebElement dragText = chromeDriver.findElementByClassName("drag_text");
			String text = dragText.getText();
			if(!"验证通过".equals(text)){
				//递归
				logger.info("拼图验证失败:[{}]",text);
				continue;
			}
			//获取验证码
			WebElement btnSmsCode = chromeDriver.findElementByClassName("btnSmsCode");
			btnSmsCode.click();
			Thread.sleep(3000L);
			WebElement errorMsg = chromeDriver.findElementByClassName("errorMsg");
			if("该手机号已被注册".equals(errorMsg.getText())){
				//拉黑手机号
				Phone.addBlackList(token,phoneNum);
				continue;
			}
			WebElement codeElement = chromeDriver.findElementByClassName("txtSmsCode");
			String smsCode = Phone.getSMSCode(token, phoneNum);
			if(StrUtil.isBlank(smsCode)){
				logger.info("短信获取失败:[{}]", smsCode);
				continue;
			}
			codeElement.sendKeys(smsCode);
			//设置密码
			WebElement chromeDriver1 = chromeDriver.findElementByClassName("password");
			chromeDriver1.sendKeys("abc123123");
			//确认注册
			WebElement submitBtn = chromeDriver.findElementByClassName("submitBtn");
			submitBtn.click();
			checkSuccess(chromeDriver,fileWriter,phoneNum,i);
		}
	}
	private static void checkSuccess(FirefoxDriver chromeDriver, FileWriter fileWriter,String phoneNum,int i){
		try {
			Thread.sleep(10000L);
			WebElement modalMsg = chromeDriver.findElementById("modalMsg");
			if ("注册成功".equals(modalMsg.getText())) {
				//结束
				fileWriter.write(phoneNum + "\r\n");
				fileWriter.flush();
				logger.info("注册完成:[{}],第[{}]个", phoneNum, i);
			}
		} catch (Exception e) {
			checkSuccess(chromeDriver,fileWriter,phoneNum,i);
		}
	}

	/**
	 * 获取拼图缺口X坐标
	 */
	public static Integer getX(String base64) {
		YdmVerify ydmVerify = new YdmVerify();
		String s = ydmVerify.sinSlideVerify(base64);
		JSONObject jsonObject = JSONUtil.parseObj(s);
		if("10000".equals(jsonObject.getStr("code"))){
			JSONObject jsonObject1 = jsonObject.getJSONObject("data");
			String data = jsonObject1.getStr("data");
			return Integer.parseInt(data)-3;
		}
		return null;
	}

	/**
	 * 修改图片比例
	 */
	public static String updateWidth(String base64) throws Exception {
		// 将 Base64 解码为 BufferedImage
		BufferedImage originalImage = base64ToBufferedImage(base64);

		// 原始图片的宽度和高度
		int originalWidth = originalImage.getWidth();
		int originalHeight = originalImage.getHeight();

		// 目标宽度
		int targetWidth = 286;

		// 按比例计算目标高度
		double scalingFactor = (double) targetWidth / originalWidth;
		int targetHeight = (int) (originalHeight * scalingFactor);

		// 缩放图片
		BufferedImage resizedImage = resizeImage(originalImage, targetWidth, targetHeight);

		/**
		 * 将缩放后的图片转换为 Base64 编码
 		 */
		return bufferedImageToBase64(resizedImage);
	}

	/**
	 * 将 Base64 字符串转换为 BufferedImage
 	 */
	public static BufferedImage base64ToBufferedImage(String base64String) throws Exception {
		byte[] decodedBytes = Base64.getDecoder().decode(base64String);
		ByteArrayInputStream inputStream = new ByteArrayInputStream(decodedBytes);
		return ImageIO.read(inputStream);
	}

	/**
	 * 按指定宽度和高度缩放图片
 	 */
	public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
		Image scaledImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
		BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
		Graphics2D g2d = resizedImage.createGraphics();
		g2d.drawImage(scaledImage, 0, 0, null);
		g2d.dispose();
		return resizedImage;
	}

	/**
	 * 将 BufferedImage 转换为 Base64 字符串
 	 */
	public static String bufferedImageToBase64(BufferedImage image) throws Exception {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ImageIO.write(image, "png", outputStream);
		byte[] imageBytes = outputStream.toByteArray();
		return Base64.getEncoder().encodeToString(imageBytes);
	}
	private static void move(FirefoxDriver driver,Integer offsetX) throws InterruptedException {
		WebElement button = driver.findElementByClassName("handler_bg");
		// 创建 Actions 实例
		Actions actions = new Actions(driver);
		actions.moveToElement(button).clickAndHold().perform();
		actions.moveByOffset(offsetX, 0).perform();
		actions.release().perform();
		Thread.sleep(3000L);
		logger.info("拼图拖动至:{}px,拖动处理完毕",offsetX);
	}
}
